﻿using Mengsk.ProxyDelivery.Domain;
using Mengsk.ProxyDelivery.Print.Domain;
using Mengsk.ProxyDelivery.Print.Domain.DeliveryNumberGenerator;
using Mengsk.ProxyDelivery.Print.Domain.PrintDataFormatters;
using Mengsk.ProxyDelivery.Service;
using Mengsk.ProxyDelivery.Utls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Xps.Packaging;

namespace Mengsk.ProxyDelivery.Print.ViewModels
{
    class PrintOrderPageViewModel : DependencyObject
    {
        public static readonly DependencyProperty ProgressProperty = DependencyProperty.Register("Progress", typeof(double), typeof(PrintOrderPageViewModel));
        public static readonly DependencyProperty PrintStateProperty = DependencyProperty.Register("PrintState", typeof(string), typeof(PrintOrderPageViewModel));
        public static readonly DependencyProperty SelectedCountProperty = DependencyProperty.Register("SelectedCount", typeof(int), typeof(PrintOrderPageViewModel));
        public static readonly DependencyProperty CurrentPrintNumberProperty = DependencyProperty.Register("CurrentPrintNumber", typeof(int), typeof(PrintOrderPageViewModel));
        public static readonly DependencyProperty InputCountProperty = DependencyProperty.Register("InputCount", typeof(int), typeof(PrintOrderPageViewModel));
        public static readonly DependencyProperty OrderViewModelsProperty = DependencyProperty.Register("OrderViewModels", typeof(List<PrintOrderViewModel>), typeof(PrintOrderPageViewModel));

        public string DeliveryTemplateName { get; set; }

        public double Progress { get { return (double)this.GetValue(ProgressProperty); } set { this.SetValue(ProgressProperty, value); } }

        public string PrintState { get { return (string)this.GetValue(PrintStateProperty); } set { this.SetValue(PrintStateProperty, value); } }

        public int SelectedCount { get { return (int)this.GetValue(SelectedCountProperty); } set { this.SetValue(SelectedCountProperty, value); } }

        public int CurrentPrintNumber { get { return (int)this.GetValue(CurrentPrintNumberProperty); } set { this.SetValue(CurrentPrintNumberProperty, value); } }

        public int InputCount { get { return (int)this.GetValue(InputCountProperty); } set { this.SetValue(InputCountProperty, value); } }

        public List<PrintOrderViewModel> OrderViewModels { get { return (List<PrintOrderViewModel>)this.GetValue(OrderViewModelsProperty); } set { this.SetValue(OrderViewModelsProperty, value); } }

        public bool IsPrinting { get; private set; }

        private bool isStop;

        private OrderPrintDocument printDoc = null;

        private PrintTemplate printTemplate = null;

        private PrintHistoryService printHistoryService = ServiceContainer.GetService<PrintHistoryService>();

        private OrderService orderService = ServiceContainer.GetService<OrderService>();

        public EventHandler Starting;

        public EventHandler Ended;


        protected virtual void OnStarting()
        {
            if (this.Starting != null)
            {
                this.Starting(this, new EventArgs());
            }
        }

        protected virtual void OnEnded()
        {
            if (this.Ended != null)
            {
                this.Ended(this, new EventArgs());
            }
        }

        private void PrintOrderViewModelCheckedHandler(object sender, EventArgs e)
        {
            this.SelectedCount = this.OrderViewModels.Count(obj => obj.IsChecked);
        }

        public PrintOrderPageViewModel(Order[] orders)
        {
            this.OrderViewModels = new List<PrintOrderViewModel>();
            DependencyPropertyDescriptor notiy = DependencyPropertyDescriptor.FromProperty(PrintOrderViewModel.IsCheckedProperty, typeof(PrintOrderViewModel));
            foreach (var item in orders.Select(obj => new PrintOrderViewModel(obj)))
            {
                notiy.AddValueChanged(item, PrintOrderViewModelCheckedHandler);
                this.OrderViewModels.Add(item);
            }
            this.Progress = 0;
            this.PrintState = "打印";
            this.PrintOrderViewModelCheckedHandler(null, null);
            //检查省市区
            foreach (var order in OrderViewModels)
            {
                order.Source.ReceiverAddress = order.Source.ReceiverAddress.Replace(",", " ").Replace("，", " ").Trim();
                try
                {
                    order.State = "";
                    order.Background = null;
                    App.DoEvents();
                    var prov = AddressService.ParseProvince(order.Source.ReceiverAddress);
                    var city = AddressService.ParseCity(order.Source.ReceiverAddress);

                    if (prov == null || city == null)
                    {
                        order.State = "未解析出省市";
                        order.Background = Brushes.Red;
                    }
                }
                catch (Exception ex)
                {
                    order.State = ex.Message;
                    order.Background = Brushes.Red;
                }
            }
        }

        public string Print(PrintDialog pd, PrintTemplate template, string currentDeliveryNumber)
        {
            try
            {
                this.CurrentPrintNumber = 0;
                this.printTemplate = template;
                this.Progress = 0;
                this.IsPrinting = true;
                this.isStop = false;
                this.OnStarting();
                this.PrintState = "取消";

                //处理订单，生成快递单号
                var wn = new WuliuNumber { DeliveryNumber = currentDeliveryNumber, WuliuId = "" };
                var ordersViewModels = this.OrderViewModels.Where(obj => obj.IsChecked).ToArray();

                foreach (var order in ordersViewModels)
                {
                    order.Source.ReceiverAddress = order.Source.ReceiverAddress.Replace(",", " ").Replace("，", " ").Trim();
                    WuliuNumber current = null;
                    if (template.PaperType == PaperType.HOT)
                    {
                        current = DeliveryNumberGeneratorManager.GenenrateOnline(template.DeliveryCompany.Title, order.Source);
                    }
                    else
                    {
                        current = wn;
                        wn = DeliveryNumberGeneratorManager.GenenrateNext(template.DeliveryCompany.Title, wn.DeliveryNumber);
                    }
                    //检查当前快递单号
                    var ret = this.printHistoryService.GetByAll(0, 0, template.DeliveryCompany.DeliveryCompany, current.DeliveryNumber, DateTime.Now.AddDays(-30), DateTime.MinValue, 0, 0);
                    if (ret.Total >= 1)
                    {
                        throw new Exception("快递单号:" + current.DeliveryNumber + "已被使用");
                    }
                    order.DeliveryCompany = template.DeliveryCompany.DeliveryCompany;
                    order.DeliveryNumber = current.DeliveryNumber;
                    order.Source.DeliveryCompany = template.DeliveryCompany.DeliveryCompany;
                    order.Source.DeliveryNumber = current.DeliveryNumber;
                    order.WuliuId = current.WuliuId;
                    App.DoEvents();

                }
                var orders = ordersViewModels.Select(obj => obj.Source).ToArray();
                //打印记录到XPS文件
                try
                {
                    string path = EnvironmentDirHelper.QINIU_SHOPERP_DIR_DATA + "\\PrintHistoryDoc\\";
                    System.IO.Directory.CreateDirectory(path);
                    path += "Print_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".xps";
                    if (File.Exists(path))
                    {
                        File.Delete(path);
                    }
                    XpsDocument xpsDoc = new XpsDocument(path, System.IO.FileAccess.ReadWrite);
                    var xpsWriter = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
                    var pDoc = new OrderPrintDocument(orders, template);
                    xpsWriter.Write(pDoc);
                    xpsDoc.Close();
                }
                catch (Exception ex)
                {
                    if (MessageBox.Show("输出备份出错：是否继续?" + Environment.NewLine + ex.Message, "错误", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
                    {
                        return "";
                    }
                }

                //输出到真实打印机
                pd.PrintTicket.PageMediaSize = new System.Printing.PageMediaSize(template.Width, template.Height);
                this.printDoc = new OrderPrintDocument(orders, template);
                this.printDoc.PrintStarting += new Action<OrderPrintDocument, Order>(printDoc_PrintStarting);
                this.printDoc.CanPrint += printDoc_CanPrint;
                pd.PrintDocument(printDoc, template.DeliveryCompany.Title);
                //储存最后一个元素
                PrintOrderViewModel vm = this.OrderViewModels.First(obj => obj.Source.Id == this.printDoc.Orders.Last().Id);
                this.UpdateDelivery(vm);
                return wn.DeliveryNumber;
            }
            finally
            {
                this.IsPrinting = false;
                this.printDoc = null;
                this.PrintState = "打印";
                this.isStop = true;
                this.OnEnded();
            }
        }

        bool printDoc_CanPrint(OrderPrintDocument arg1, Order arg2)
        {
            if (this.isStop)
            {
                throw new Exception("已停止打印");
            }
            int index = arg1.SourceOrders.FindIndex(obj => obj.Id == arg2.Id);
            this.Progress = (index + 1) * 1.0 / arg1.SourceOrders.Count;
            this.CurrentPrintNumber = index + 1;
            if (this.orderService.CanPrintOrder(arg2.Id) == false)
            {
                PrintOrderViewModel vm = this.OrderViewModels.FirstOrDefault(obj => obj.Source.Id == arg2.Id);
                vm.State = "跳过打印";
                vm.Background = Brushes.Red;
                return false;
            }
            return true;
        }

        public void Stop()
        {
            if (this.IsPrinting && this.printDoc != null)
            {
                this.printDoc.CancelAsync(null);
            }
            this.isStop = true;
        }

        private void printDoc_PrintStarting(OrderPrintDocument sender, Order order)
        {
            //上传前一个
            PrintOrderViewModel preOne = this.OrderViewModels.LastOrDefault(obj => obj.State == "正在打印" && obj.Source.Id != order.Id);
            if (preOne != null && preOne.Source.Id != order.Id)
            {
                this.UpdateDelivery(preOne);
            }
            Thread.Sleep(30);
            //打印当前的
            PrintOrderViewModel vm = this.OrderViewModels.FirstOrDefault(obj => obj.Source.Id == order.Id);
            vm.State = "正在打印";
            vm.Background = Brushes.Yellow;
            App.DoEvents();
        }

        private void UpdateDelivery(PrintOrderViewModel vm)
        {
            try
            {
                App.DoEvents();
                if (string.IsNullOrWhiteSpace(vm.DeliveryCompany) || string.IsNullOrWhiteSpace(vm.DeliveryNumber))
                {
                    throw new Exception("物流公司和编号为空");
                }
                PrintHistory ph = new PrintHistory
                {
                    UploadTime = DateTime.MinValue,
                    DeliveryCompany = vm.DeliveryCompany,
                    DeliveryNumber = vm.DeliveryNumber,
                    DeliveryTemplateName = this.printTemplate.Name,
                    Operator = "",
                    OrderId = vm.Source.Id,
                    PopBuyerId = vm.Source.PopBuyerId,
                    PopType = vm.Source.PopType,
                    PopOrderMoney = vm.Source.PopOrderMoney,
                    ReceiverAddress = vm.Source.ReceiverAddress,
                    ReceiverMobile = vm.Source.ReceiverMobile,
                    ReceiverName = vm.Source.ReceiverName,
                    ReceiverPhone = vm.Source.ReceiverPhone,
                    PrintTime = DateTime.Now,
                    SenderName = vm.SenderName,
                    SenderPhone = vm.SenderPhone,
                    SellerId = vm.Source.SellerId,
                    Uploaded = false,
                    GoodsInfo = vm.Goods,
                    GiftInfo = vm.Gifts,
                    PaperType = this.printTemplate.PaperType,
                    WuliuId = vm.WuliuId,
                };
                this.printHistoryService.Insert(ph);
                vm.State = "打印成功";
                App.DoEvents();
                vm.Background = null;
            }
            catch (Exception ex)
            {
                vm.State = "打印成功" + ex.Message;
                vm.Background = Brushes.Red;
            }
        }
    }
}
